﻿using com.yoozoo.gta.Gameplay.PVE;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using Yoozoo.Managers.ResourceManagerV2.Runtime;
using Object = UnityEngine.Object;

namespace Gameplay.PVE
{
    public class PveSceneResourceManager
    {
        private ResLoader _mapResLoader;
        private PveSceneMapPool pveScene;
        private GgameSceneConfig pveSceneConfig;
        private List<Texture2D> lightMapColors;
        private List<Texture2D> lightMapDirs;
        private GameObject postProcessCamera;
        private GameObject skyBoxObject;
        private ResLoader lightMapLoader;
        private ResLoader mapObjLoader;
        private int loadSceneStage = 0;
        private Action onLoadOverAction;
        private Material skyBoxMaterial;
        private Cubemap reflectionProbe;
        public static Stack<GameObject> pathPoints = new Stack<GameObject>(3);
        public static SceneSeparateManager sceneSeparateMgr;

        
        public GameObject sceneRoot;

        public void Initialize()
        {

        }
        public void Dispose()
        {
            sceneSeparateMgr.Dispose();
            sceneSeparateMgr = null;
            
            _mapResLoader.Recycle2Cache();
            _mapResLoader = null;
            lightMapLoader.Recycle2Cache();
            lightMapLoader = null;
            mapObjLoader.Recycle2Cache();
            mapObjLoader = null;
            GameObject.Destroy(postProcessCamera);
            GameObject.Destroy(skyBoxObject);
            pveScene = null;
            pveSceneConfig = null;
            loadSceneStage = 0;
            onLoadOverAction = null;
            lightMapColors = null;
            lightMapDirs = null;

            RenderSettings.skybox = null;
            if (skyBoxMaterial)
            {
                GameObject.DestroyImmediate(skyBoxMaterial);
            }
        }
        public void LoadScene(int sceneId,GameObject resRoot, Action onLoadOverAction,bool isPveScene)
        {
            if (!isPveScene)
            {
                Debug.LogEditorError("目前rpg没有用到加载场景，如果需要用到需要重构此函数");
                //目前rpg没有用到加载场景，如果需要用到需要重构此函数，加载不同的id需要销毁上一次的场景，否则会导致pve重复加载
                onLoadOverAction?.Invoke();
                return;
            }
            this.onLoadOverAction = onLoadOverAction;
            if (pveScene != null)
            {
                if (pveScene.id == sceneId)
                {
                    onLoadOverAction?.Invoke();
                    return;
                }
            }
            loadSceneStage = 0;

            pveScene = new PveSceneMapPool
            {
                id = sceneId,
            };

            var path = PveResourceManager.Instance.GetRpgResourceFullPath(sceneId);
            if (_mapResLoader == null)
            {
                _mapResLoader = ResLoader.Alloc();
            }
            
            _mapResLoader.Add2Load(path, (success, assetName, asset) =>
            {
                if (success)
                {
                    SceneSeparateManagerData ssmd = asset as SceneSeparateManagerData;
                    sceneRoot = new GameObject("sceneRoot");
                    sceneRoot.name = "sceneRoot";
                    sceneSeparateMgr =  sceneRoot.AddComponent<SceneSeparateManager>();
                    sceneSeparateMgr.InitData(ssmd);
                    //pveSceneConfig = ssmd.mapData;
                    //下面这俩还需要么？
                    pveScene.prefabPool = new Dictionary<int, PveSceneMapPrefabPool>();
                    pveScene.gpuDataPool = new List<PveSceneGpuData>();
                    pveScene.SceneRoot = sceneRoot;
                    lightMapLoader = ResLoader.Alloc();
                    lightMapColors = new List<Texture2D>();
                    lightMapDirs = new List<Texture2D>();
                    for (int i = 0; i < pveSceneConfig.RenderData.lightMapColorPath.Count; i++)
                    {
                        int index = i;
                        lightMapColors.Add(null);
                        lightMapLoader.Add2Load(pveSceneConfig.RenderData.lightMapColorPath[i], (s, an, a) =>
                        {
                            if (s)
                            {
                                lightMapColors[index] = a as Texture2D;
                            }
                        });
                    }

                    for (int i = 0; i < pveSceneConfig.RenderData.lightMapDirPath.Count; i++)
                    {
                        int index = i;
                        lightMapDirs.Add(null);
                        lightMapLoader.Add2Load(pveSceneConfig.RenderData.lightMapDirPath[i], (s, an, a) =>
                        {
                            if (s)
                            {
                                lightMapDirs[index] = a as Texture2D;
                            }
                        });
                    }
                    
                    lightMapLoader.Add2Load(pveSceneConfig.RenderData.skyBoxMaterialPath, (s, an, a) =>
                    {
                        if (s && a != null && a is Material go)
                        {
                            skyBoxMaterial = Material.Instantiate(go);
                            RenderSettings.skybox = skyBoxMaterial;
                        }

                        RenderSettings.ambientMode = pveSceneConfig.RenderData.ambientMode;
                    });
                    //这里不需要了，注掉
                    // lightMapLoader.Add2Load(pveSceneConfig.RenderData.reflectionProbePath, (s, an, a) =>
                    // {
                    //     if (s && a != null && a is Cubemap go)
                    //     {
                    //         reflectionProbe = go;
                    //     }
                    // });

                    //TODO:不需要再生成
                    LoadGroupData(() =>
                    {
                        loadSceneStage++;
                        CheckLoadOver();
                    });

                    lightMapLoader.Load(() =>
                    {
                        loadSceneStage++;
                        CheckLoadOver();
                    });
                }
            });
            _mapResLoader.Load();
        }

        /// <summary>
        /// 卸载挂机资源
        /// </summary>
        public void UnloadPveResource()
        {
            pveScene?.DestoryGameObject();
        }
        private void CheckLoadOver()
        {
            if (loadSceneStage == 2)
            {
                onLoadOverAction.Invoke();
                onLoadOverAction = null;
            }
        }

        private void LoadGroupData(Action action)
        {
            mapObjLoader = ResLoader.Alloc();

            var path = PveResourceManager.Instance.GetRpgResourceFullPath(30000002);
            if (mapObjLoader == null)
            {
                mapObjLoader = ResLoader.Alloc();
            }

            mapObjLoader.Add2Load(path, (success, assetName, asset) =>
            {
                if (success)
                {
                    NpcGroupData groupData = asset as NpcGroupData;
                    sceneSeparateMgr.groupData = groupData;
                }
            });

            mapObjLoader.Load(action);
        }
        public GameObject GetPostProcessCamera()
        {
            return postProcessCamera;
        }   

        public GameObject GetPveSceneMapPrefab(int part)
        {
            return pveScene.GetPrefabRoot(part);
        }

        public void RecoverPveSceneMapPrefab(GameObject prefab, int part)
        {
            pveScene.RecoverPrefabRoot(part, prefab);
        }

        public GameObject GetPathPoints()
        {
            return pathPoints.Pop();
        }

        public void ClearPathPoints()
        {
            pveScene.ClearPathPoints();
        }

        public void RecoverPathPoints(GameObject prefab)
        {
            pathPoints.Push(prefab);
        }
      
        public List<PveSceneGpuData> GetPveSceneGpuData()
        {
            return pveScene.gpuDataPool;
        }
        public GameObject GetSkyBoxObject()
        {
            return skyBoxObject;
        }

        public List<Texture2D> GetLightMapColor()
        {
            return lightMapColors;
        }

        public List<Texture2D> GetLightMapDir()
        {
            return lightMapDirs;
        }

        public Material GetSkyBoxMaterial()
        {
            return skyBoxMaterial;
        }
        public  Color GetAmbientColor()
        {
            return pveSceneConfig.RenderData.ambientColor;
        }

        public DefaultReflectionMode GetReflectionMode()
        {
            return pveSceneConfig.RenderData.reflectionMode;
        }

        public Cubemap GetReflectionProbe()
        {
            return reflectionProbe;
        }
        public class PveSceneMapPool
        {
            public int id;
            public Dictionary<int, PveSceneMapPrefabPool> prefabPool;
            public List<PveSceneGpuData> gpuDataPool;
            public GameObject SceneRoot;

            public GameObject GetPathPoints()
            {
                return pathPoints.Pop();
            }

            public void ClearPathPoints()
            {
                while (pathPoints.Count > 0)
                {
                    var go = pathPoints.Pop();
                    GameObject.Destroy(go);
                }
            }

            public void RecoverPathPoints(GameObject obj)
            {
                pathPoints.Push(obj);
            }
            
            public GameObject GetPrefabRoot(int partIndex)
            {
                if (prefabPool.TryGetValue(partIndex, out var pool))
                {
                    return pool.GetPrefabRoot();
                }
                return null;
            }

            public void RecoverPrefabRoot(int partIndex, GameObject obj)
            {
                if (prefabPool.TryGetValue(partIndex, out var pool))
                {
                    pool.RecoverPrefabRoot(obj);
                }
            }

            public void DestoryGameObject()
            {
                foreach (var prefabPool in prefabPool)
                {
                    prefabPool.Value.DestoryGameObject();
                }

                prefabPool.Clear();
                prefabPool = null;
            }
        }
        public class PveSceneGpuData
        {
            public string meshPath;
            public string matPath;
            public Mesh mesh;
            public Material material;
            public List<PrefabData> objs;
        }

        public class PveSceneMapPrefabPool
        {
            public List<PrefabData> data;
            public List<GameObject> roots;
            public List<GameObject> availableRoots;
            
            public GameObject GetPrefabRoot()
            {
                if (availableRoots.Count == 0)
                {
                    Debug.LogError("地图缓存数据为0");
                    return null;
                }
                var index = availableRoots.Count - 1;
                var obj = availableRoots[index];
                availableRoots.RemoveAt(index);
                obj.SetActive(true);
                return obj;
            }

            public void RecoverPrefabRoot(GameObject root)
            {
                root.SetActive(false);
                availableRoots.Add(root);
            }

            public void DestoryGameObject()
            {
                data = null;
                foreach (var root in roots)
                {
                    Object.Destroy(root);
                }
                foreach (var root in availableRoots)
                {
                    Object.Destroy(root);
                }

                roots = null;
                availableRoots = null;
            }
        }

        public GgameSceneConfig GetSceneConfig()
        {
            return pveSceneConfig;
        }
    }

}
